#include "FileOperator.h"
#include "windows.h"

VFILE os_Open(const char *filename, OpenMode mode)
{
	HANDLE hFile = NULL;
	if (mode == FO_READ)
	{
		hFile = (HANDLE)CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); 
		if (hFile == INVALID_HANDLE_VALUE) 
		{ 
			return NULL;
		} 
	}
	else if (mode == FO_WRITE)
	{
		hFile = (HANDLE)CreateFile(filename, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, NULL, NULL); 
		if (hFile == INVALID_HANDLE_VALUE) 
		{ 
			int nErr = GetLastError();
			return NULL;
		}
	}
	return hFile;
}

bool os_Read(VFILE handle, void *buffer, unsigned int readlen)
{
	DWORD dwRead = 0;
	HANDLE hFile = (HANDLE)handle;
	if(!ReadFile(hFile, buffer, readlen, &dwRead, NULL))
	{
		int nErr = GetLastError();
		return false;
	}
	return true;
}

bool os_Write(VFILE handle, void *buffer, unsigned int readlen)
{
	HANDLE hFile = (HANDLE)handle;
	DWORD len = 0;
	BOOL bRet = WriteFile(hFile, buffer, readlen, &len, NULL);
	return bRet == TRUE;
}

void os_Seek(VFILE handle, __int64 offset, FILEPOS origin)
{
	HANDLE hFile = (HANDLE)handle;
	LONG lHigh = LONG((offset >> 32) & 0x00000000FFFFFFFF);
	LONG lLow = LONG(offset & 0x00000000FFFFFFFF);
	switch(origin)
	{
	case F_BEGIN:
		::SetFilePointer(hFile, lLow, &lHigh, FILE_BEGIN);
		break;
	case F_END:
		::SetFilePointer(hFile, lLow, &lHigh, FILE_END);
		break;
	case F_CURRENT:
		::SetFilePointer(hFile, lLow, &lHigh, FILE_CURRENT);
		break;
	}
}

void os_Close(VFILE handle)
{
	HANDLE hFile = (HANDLE)handle;
	CloseHandle(handle);
}

__int64 os_Getsize(VFILE handle)
{
	HANDLE hFile = (HANDLE)handle;
	DWORD dwHigh = 0;
	DWORD dwLow = GetFileSize(hFile, &dwHigh);
	__int64 llHigh = dwHigh; 
	llHigh = (llHigh << 32) & 0xffffffff00000000;
	__int64 llFileSize = llHigh + dwLow;
	return llFileSize;
}
